package cn.tannn.ops.pwd.strategy.impl;

import cn.tannn.jdevelops.exception.built.BusinessException;
import cn.tannn.ops.pwd.strategy.EncryptStrategy;
import lombok.SneakyThrows;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * AES  加解密策略具体实现
 *
 * @author tnnn
 * @version V1.0
 * @date 2023-02-20 10:24
 */
public class EncryptStrategyAES implements EncryptStrategy {

    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
    private static final String ALGORITHM = "AES";
    /**
     * 目前无法实现多次加解密
     */
    @SneakyThrows
    @Override
    public String encrypt(String secret, String content, Integer count) {
        return encoder(secret, content);
    }


    /**
     * 目前无法实现多次加解密
     */
    @SneakyThrows
    @Override
    public String decrypt(String secret, String content, Integer count) {
        return decode(secret, content);
    }


    /**
     * 加密
     */
    private String encoder(String key, String content) throws Exception {
        // 1. 生成密钥
        byte[] keyBytes = createKey(key);
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM);

        // 2. 初始化加密器
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

        // 3. 加密
        byte[] encryptedBytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    /**
     * 解密
     */
    private String decode(String key, String content) {
        try {
            // 1. 生成密钥
            byte[] keyBytes = createKey(key);
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM);

            // 2. 初始化解密器
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);

            // 3. 解密
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(content));
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new BusinessException("解密失败，请检查密钥是否正确", e);
        }
    }

    /**
     * 生成固定长度的密钥
     */
    private byte[] createKey(String key) throws Exception {
        MessageDigest digest = MessageDigest.getInstance("MD5");
        return digest.digest(key.getBytes(StandardCharsets.UTF_8));
    }
}
